`timescale 1ns / 1ps
/*
 * Copyright (c) 2020-2021, SERI Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-29     Lyons        first version
 */

module pa_chip_top (
    clk_i,                      // system clock
    rst_n_i,                    // system reset

    rxd,                        // UART RX pin
    txd                         // UART TX pin
    );

`include "pa_chip_param.v"

input                           clk_i;
input                           rst_n_i;

input                           rxd;
output                          txd;

wire                            clk_i;
wire                            rst_n_i;

wire                            rxd;
wire                            txd;


wire [`ADDR_BUS_WIDTH-1:0]      m_addr;
wire [`DATA_BUS_WIDTH-1:0]      m_rdata;
wire [`DATA_BUS_WIDTH-1:0]      m_wdata;
wire [2:0]                      m_wsize;
wire                            m_we;

wire [`ADDR_BUS_WIDTH-1:0]      s0_addr;
wire [`DATA_BUS_WIDTH-1:0]      s0_rdata;
wire [`DATA_BUS_WIDTH-1:0]      s0_wdata;
wire                            s0_we;

wire [`ADDR_BUS_WIDTH-1:0]      s1_addr;
wire [`DATA_BUS_WIDTH-1:0]      s1_rdata;
wire [`DATA_BUS_WIDTH-1:0]      s1_wdata;
wire [2:0]                      s1_wsize;
wire                            s1_we;

wire [`ADDR_BUS_WIDTH-1:0]      s2_addr;
wire [`DATA_BUS_WIDTH-1:0]      s2_rdata;
wire [`DATA_BUS_WIDTH-1:0]      s2_wdata;
wire                            s2_we;

wire [`ADDR_BUS_WIDTH-1:0]      s3_addr;
wire [`DATA_BUS_WIDTH-1:0]      s3_rdata;
wire [`DATA_BUS_WIDTH-1:0]      s3_wdata;
wire                            s3_we;

wire [`ADDR_BUS_WIDTH-1:0]      s4_addr;
wire [`DATA_BUS_WIDTH-1:0]      s4_rdata;
wire [`DATA_BUS_WIDTH-1:0]      s4_wdata;
wire                            s4_we;

wire [`ADDR_BUS_WIDTH-1:0]      s5_addr;
wire [`DATA_BUS_WIDTH-1:0]      s5_rdata;
wire [`DATA_BUS_WIDTH-1:0]      s5_wdata;
wire                            s5_we;

wire [`ADDR_BUS_WIDTH-1:0]      s6_addr;
wire [`DATA_BUS_WIDTH-1:0]      s6_rdata;
wire [`DATA_BUS_WIDTH-1:0]      s6_wdata;
wire                            s6_we;


wire                            clk_50m;
wire                            rst_n;

assign clk_50m = clk_i;
assign rst_n = rst_n_i;

wire                            irq_flag;

pa_core_top u_pa_core_top (
    .clk_i                      (clk_50m),
    .rst_n_i                    (rst_n),

    .irq_i                      (irq_flag),

    .rom_addr_i                 (s0_addr),
    .rom_data_i                 (s0_rdata),
    .rom_data_o                 (s0_wdata),
    .rom_we_i                   (s0_we),

    .rbm_addr_o                 (m_addr),
    .rbm_size_o                 (m_wsize),
    .rbm_data_o                 (m_wdata),
    .rbm_data_i                 (m_rdata),
    .rbm_we_o                   (m_we)
);

pa_soc_rbm u_pa_soc_rbm (
    .m_addr_i                   (m_addr),
    .m_data_i                   (m_wdata),
    .m_data_o                   (m_rdata),
    .m_we_i                     (m_we),

//  0x0000_0000 ~ 0x0fff_ffff
    .s0_addr_o                  (s0_addr),
    .s0_data_i                  (s0_wdata),
    .s0_data_o                  (s0_rdata),
    .s0_we_o                    (s0_we),

//  0x1000_0000 ~ 0x1fff_ffff
    .s1_addr_o                  (s1_addr),
    .s1_data_i                  (s1_wdata),
    .s1_data_o                  (s1_rdata),
    .s1_we_o                    (s1_we),

//  0x2000_0000 ~ 0x2fff_ffff
    .s2_addr_o                  (s2_addr),
    .s2_data_i                  (s2_wdata),
    .s2_data_o                  (s2_rdata),
    .s2_we_o                    (s2_we),

//  0x3000_0000 ~ 0x3fff_ffff
    .s3_addr_o                  (s3_addr),
    .s3_data_i                  (s3_wdata),
    .s3_data_o                  (s3_rdata),
    .s3_we_o                    (s3_we),

//  0x4000_0000 ~ 0x4fff_ffff
    .s4_addr_o                  (s4_addr),
    .s4_data_i                  (s4_wdata),
    .s4_data_o                  (s4_rdata),
    .s4_we_o                    (s4_we),

//  0x5000_0000 ~ 0x5fff_ffff
    .s5_addr_o                  (s5_addr),
    .s5_data_i                  (s5_wdata),
    .s5_data_o                  (s5_rdata),
    .s5_we_o                    (s5_we),

//  0x6000_0000 ~ 0x6fff_ffff
    .s6_addr_o                  (s6_addr),
    .s6_data_i                  (s6_wdata),
    .s6_data_o                  (s6_rdata),
    .s6_we_o                    (s6_we)
);

assign s1_wsize[2:0] = m_wsize[2:0]; // only memory use

pa_soc_ram u_pa_soc_ram (
    .clk_i                      (clk_50m),
    .rst_n_i                    (rst_n),

    .addr_i                     (s1_addr),

    .data_we_i                  (s1_we),
    .data_size_i                (s1_wsize),
    .data_i                     (s1_rdata),

    .data_o                     (s1_wdata)
);

pa_perips_timer u_pa_perips_timer1 (
    .clk_i                      (clk_50m),
    .rst_n_i                    (rst_n),

    .addr_i                     (s2_addr[7:0]),

    .data_we_i                  (s2_we),
    .data_i                     (s2_rdata),

    .data_o                     (s2_wdata),

    .irq_o                      (irq_flag)
);

pa_perips_uart u_pa_perips_uart1 (
    .clk_i                      (clk_50m),
    .rst_n_i                    (rst_n),

    .addr_i                     (s3_addr[7:0]),

    .data_we_i                  (s3_we),
    .data_i                     (s3_rdata),

    .data_o                     (s3_wdata),

    .pad_rxd                    (rxd),
    .pad_txd                    (txd)
);

wire                            PAD_A2;
wire                            PAD_A3;

pa_perips_uart u_pa_perips_uart2 (
    .clk_i                      (clk_50m),
    .rst_n_i                    (rst_n),

    .addr_i                     (s4_addr[7:0]),

    .data_we_i                  (s4_we),
    .data_i                     (s4_rdata),

    .data_o                     (s4_wdata),

    .pad_rxd                    (PAD_A2),
    .pad_txd                    (PAD_A3)
);

pa_perips_uart u_pa_perips_uart3 (
    .clk_i                      (clk_50m),
    .rst_n_i                    (rst_n),

    .addr_i                     (s5_addr[7:0]),

    .data_we_i                  (s5_we),
    .data_i                     (s5_rdata),

    .data_o                     (s5_wdata),

    .pad_rxd                    (PAD_A3),
    .pad_txd                    (PAD_A2)
);

assign s6_wdata[`DATA_BUS_WIDTH-1:0] = 32'b0;

endmodule